import nest_asyncio
import asyncio
import re
import signal
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Application, CommandHandler, CallbackQueryHandler, ContextTypes

nest_asyncio.apply()

# Глобальная переменная для хранения таймеров
timers = {}

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /start. Отправляет приветственное сообщение."""
    await update.message.reply_text('Привет! Введи команду /set <время> <текст> для установки таймера.')

async def set_timer(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик команды /set. Устанавливает новый таймер."""
    chat_id = update.message.chat_id
    try:
        print("Добавление таймера...")
        # Получаем время и текст из команды
        time_str = context.args[0]
        custom_text = ' '.join(context.args[1:])

        # Преобразуем время в секунды
        hours, minutes, seconds = 0, 0, 0
        if 'h' in time_str:
            hours = int(time_str.replace('h', ''))
        elif 'm' in time_str:
            minutes = int(time_str.replace('m', ''))
        elif 's' in time_str:
            seconds = int(time_str.replace('s', ''))

        total_seconds = hours * 3600 + minutes * 60 + seconds

        if total_seconds <= 0:
            await update.message.reply_text('Время должно быть больше нуля.')
            return

        # Инициализируем список таймеров для чата, если его ещё нет
        if chat_id not in timers:
            timers[chat_id] = []

        # Создаём новый таймер и добавляем его в список
        timer = asyncio.create_task(notify(context, update, custom_text, total_seconds))
        timers[chat_id].append({"timer": timer, "time": total_seconds, "text": custom_text, "message_id": update.message.message_id, "update": update})

        print("Таймер добавлен.")
        await update.message.reply_text(f'Таймер установлен на {time_str} с текстом: "{custom_text}"')

    except (IndexError, ValueError):
        await update.message.reply_text('Использование: /set <время> <текст>')

async def notify(context: ContextTypes.DEFAULT_TYPE, update: Update, custom_text: str, delay: int) -> None:
    """Отправляет сообщение с таймером и кнопками."""
    await asyncio.sleep(delay)
    chat_id = update.message.chat_id

    # Создаём клавиатуру с кнопками
    keyboard = [
        [
            InlineKeyboardButton("Я собрал!", callback_data='restart'),
            InlineKeyboardButton("Стоп", callback_data='stop')
        ]
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)

    # Отправляем сообщение с кнопками и получаем его message_id
    message = await context.bot.send_message(chat_id, text=f'Время вышло! {custom_text}', reply_markup=reply_markup)
    message_id = message.message_id

    # Обновляем message_id в словаре timers
    for timer_data in timers.get(chat_id, []):
        if timer_data["timer"] == asyncio.current_task():
            timer_data["message_id"] = message_id
            break

async def button(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Обработчик нажатий на кнопки."""
    query = update.callback_query
    await query.answer()

    chat_id = query.message.chat_id
    message_id = query.message.message_id

    # print(f"Обработка кнопки в чате {chat_id}, сообщение {message_id}")
    # print(f"Данные таймера: {timers}")

    if query.data == 'restart':
        # Находим таймер для перезапуска
        timer_to_restart = None
        for i, timer_data in enumerate(timers.get(chat_id, [])):
            # if timer_data["message_id"] == message_id:
            if timer_data["message_id"] == message_id:
                timer_to_restart = i
                # print(f"Таймер для перезапуска найден: {timer_to_restart}")
                break

        if timer_to_restart is not None:
            print("Перезапуск таймера...")
            timer_data = timers[chat_id].pop(timer_to_restart)
            timer_data["timer"].cancel()

            # Создаём новый таймер с теми же параметрами, используя сохранённый 'update'
            new_timer = asyncio.create_task(notify(context, timer_data["update"], timer_data["text"], timer_data["time"]))
            timers[chat_id].append({"timer": new_timer, "time": timer_data["time"], "text": timer_data["text"], "message_id": message_id, "update": timer_data["update"]})

            # Удаляем сообщение с кнопками
            await query.message.delete()

        else:
            print("Таймер для перезапуска не найден!")
    elif query.data == 'stop':
        # Находим таймер для остановки
        timer_to_stop = None
        for i, timer_data in enumerate(timers.get(chat_id, [])):
            # print(f"Проверка таймера {i}, message_id: {timer_data['message_id']}, сравниваем с: {message_id}")
            if timer_data["message_id"] == message_id:
                timer_to_stop = i
                break

        if timer_to_stop is not None:
            timers[chat_id][timer_to_stop]["timer"].cancel()
            del timers[chat_id][timer_to_stop]

            await context.bot.delete_message(chat_id=chat_id, message_id=message_id)

async def main() -> None:
    """Запускает бота."""
    application = Application.builder().token("YOUR_TOKEN").build()

    # Добавляем обработчики команд и кнопок
    application.add_handler(CommandHandler("start", start))
    application.add_handler(CommandHandler("set", set_timer))
    application.add_handler(CallbackQueryHandler(button))

    print("Bot started...")

    # Запускаем бота
    await application.run_polling()

async def shutdown(application: Application):
    """Останавливает бота."""
    print("Останавливаем приложение...")
    await application.stop()
    print("Приложение остановлено.")

if __name__ == '__main__':
    app = asyncio.run(main())
    loop = asyncio.get_event_loop()

    # Добавляем обработчик сигнала для корректного завершения
    for signame in ('SIGINT', 'SIGTERM'):
        loop.add_signal_handler(getattr(signal, signame), lambda: asyncio.create_task(shutdown(app)))

    loop.run_forever()